package cn.iocoder.yudao.module.engine.service.core.filter.read.base;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.module.engine.constant.EngineConstant;
import cn.iocoder.yudao.module.engine.enums.EnumAudioType;
import cn.iocoder.yudao.module.engine.enums.EnumInteractionType;
import cn.iocoder.yudao.module.engine.enums.SensorTypeEnum;
import cn.iocoder.yudao.module.engine.model.context.ControlEngineContext;
import cn.iocoder.yudao.module.engine.model.engine.EngineInputData;
import cn.iocoder.yudao.module.engine.model.engine.EngineOutputData;
import cn.iocoder.yudao.module.engine.prometheus.EngineWebSocketMessageMetrics;
import cn.iocoder.yudao.module.engine.service.core.pipeline.FilterAdapter;
import cn.iocoder.yudao.module.engine.service.core.pipeline.FilterContext;
import cn.iocoder.yudao.module.engine.service.core.queue.audio.AudioQueueManager;
import cn.iocoder.yudao.module.engine.service.log.IEngineLogService;
import cn.iocoder.yudao.module.engine.util.AudioUtils;
import cn.iocoder.yudao.module.engine.util.EngineConvertUtils;
import cn.iocoder.yudao.module.engine.util.SensorUtils;
import cn.iocoder.yudao.module.resource.api.IAudioServiceApi;
import cn.iocoder.yudao.module.resource.api.enums.MessageSourceTypeEnum;
import cn.iocoder.yudao.module.resource.api.model.AudioDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
import java.util.List;

@Slf4j
public abstract class AbstractThreeAxisSensor2AudioFilter extends FilterAdapter {
    @Resource
    private IAudioServiceApi audioApi;
    @Resource
    private IEngineLogService logService;
    @Resource
    private EngineWebSocketMessageMetrics messageMetrics;
    @Resource
    private AudioQueueManager audioQueueManager;

    public abstract List<String> triggerThreeAxisSensor(ControlEngineContext engineContext,
                                                        EngineInputData.Sensor sensor);

    public abstract EnumAudioType getAudioType();

    @Override
    public void read(FilterContext ctx, ControlEngineContext engineContext) throws Exception {
        final List<EngineInputData.Sensor> sensors = engineContext.getInputData().getSensors();
        if (CollUtil.isEmpty(sensors)) {
            ctx.fireRead(engineContext);
            return;
        }

        final EngineInputData.Sensor sensor = SensorUtils.getSensor(sensors, SensorTypeEnum.THREE_AXIS);
        if (sensor == null) {
            ctx.fireRead(engineContext);
            return;
        }

        final List<String> queryTags = triggerThreeAxisSensor(engineContext, sensor);
        if (CollUtil.isEmpty(queryTags)) {
            ctx.fireRead(engineContext);
            return;
        }

        final List<AudioDTO> audios = audioApi.queryAudioByTag(engineContext.getRoleId(), queryTags);
        log.info("查询传感器对应的音频, audiosSize = {}", audios.size());
        if (CollUtil.isEmpty(audios)) {
            logService.log(engineContext, "【未查询到该标签的音频】" + String.join(",", queryTags));
        }

        final AudioDTO audioDto = AudioUtils.randomAudio(engineContext.getSessionCtx(), audios);
        log.info("随机传感器对应的音频: {}", JsonUtils.toJsonString(audioDto));

        final EngineOutputData.Audio mainAudio = EngineConvertUtils.toEngineOutputData(
                engineContext.getUserText(), engineContext.getChatId(),
                MessageSourceTypeEnum.SYSTEM, getAudioType(), audioDto);

        audioQueueManager.addAndSendAudio(engineContext, null, mainAudio);
        messageMetrics.recordSuccessRequest(EnumInteractionType.SENSOR, EngineConstant.ENGINE_INPUT_MAPPING);
        messageMetrics.recordSuccessRequestDuration(EnumInteractionType.SENSOR, EngineConstant.ENGINE_INPUT_MAPPING, 1, Duration.between(engineContext.getWebsocketStart(), Instant.now()));

        ctx.fireRead(engineContext);
    }

    public static void main(String[] args) {
        String key = RandomUtil.randomString(256 / 8);
        System.out.println(key);

        AES aes = SecureUtil.aes(key.getBytes(StandardCharsets.UTF_8));
        aes.setIv("lmrobot@2025".getBytes(StandardCharsets.UTF_8));

        String s = aes.encryptBase64("abc".getBytes(StandardCharsets.UTF_8));
        System.out.println(s);
    }

}
